package com.huawei.chengdu.meetingdemo.view.dialogs;

import android.content.Context;
import android.view.Gravity;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.device.idea.meeting.ConfCtrl.model.ParticipantInfo;
import com.device.idea.meeting.ConfCtrl.model.TermCtrlSiteInfo;
import com.device.idea.meeting.Const.EventMsg;
import com.device.idea.meeting.MeetingCallback;
import com.huawei.chengdu.meetingdemo.R;
import com.huawei.chengdu.meetingdemo.consts.ObserverConts;
import com.huawei.chengdu.meetingdemo.consts.ConfConst;
import com.huawei.chengdu.meetingdemo.model.ConfSiteInfo;
import com.huawei.chengdu.meetingdemo.model.GalleryBean;
import com.huawei.chengdu.meetingdemo.util.AppContext;
import com.huawei.chengdu.meetingdemo.util.LogUtil;
import com.huawei.chengdu.meetingdemo.view.IViewDataObserver;
import com.huawei.chengdu.meetingdemo.presenter.MeetingManager;
import com.huawei.chengdu.meetingdemo.view.adapter.ParticipantsAdapter;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class ParticipantsDialog extends FloatWindowBase implements IViewDataObserver {
    private static final String TAG = ParticipantsDialog.class.getSimpleName();

    private LinearLayout llSecondSpokesman;

    private TextView tvParticipantsCount;

    private TextView tvSpokesman;

    private TextView tvSecondSpokesman;

    private TextView tvMuteAll;

    private RecyclerView rvSites;

    private ImageView ivClose;

    private ParticipantsAdapter participantsAdapter;

    private boolean isMeChairman;

    private boolean isHasChair;

    private boolean isAllMuted;

    /**
     * 构造方法
     *
     * @param context 上下文
     * @param posX    父布局的X坐标
     * @param posY    父布局的Y坐标
     */
    public ParticipantsDialog(Context context, int posX, int posY) {
        super(context);
        super.setWmTitleParams(TAG);
        this.posX = posX;
        this.posY = posY;
        initView();
        initEvent();
    }

    @Override
    protected int getLayoutId() {
        return R.layout.sites_dialog_layout;
    }

    @Override
    protected String getChildName() {
        return TAG;
    }

    private void initView() {
        llSecondSpokesman = mRootView.findViewById(R.id.ll_second_spokesman);
        tvParticipantsCount = mRootView.findViewById(R.id.tv_participant_count);
        tvSpokesman = mRootView.findViewById(R.id.tv_spokesman_name);
        tvSecondSpokesman = mRootView.findViewById(R.id.tv_spokesman_name_second);
        tvMuteAll = mRootView.findViewById(R.id.tv_mute_all);
        ivClose = mRootView.findViewById(R.id.iv_close);
        rvSites = mRootView.findViewById(R.id.rv_participants_list);

        initRecyclerView();
        initChairStatus();
        initLayoutParams();
    }

    /**
     * 初始化数据
     */
    public void initData() {
        initParticipantInfo();
        registerListenerService();
    }

    private void initRecyclerView() {
        LinearLayoutManager layoutManager = new LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, false);
        rvSites.setLayoutManager(layoutManager);
        participantsAdapter = new ParticipantsAdapter(mContext, this);
        rvSites.setAdapter(participantsAdapter);
        participantsAdapter.notifyDataSetChanged();
    }

    private void initChairStatus() {
        isMeChairman = MeetingManager.getInstance().isMeChairman();
        isHasChair = MeetingManager.getInstance().isHasChairman();
        // 如果是主席，显示全部静音
        if (isMeChairman) {
            // 是否是全部闭音
            tvMuteAll.setText(isAllMuted ? R.string.cancel_mute_all : R.string.mute_all);
            tvMuteAll.setVisibility(View.VISIBLE);
        } else { // 非主席，申请主席或不显示
            tvMuteAll.setVisibility(View.GONE);
        }
    }

    private void initLayoutParams() {
        LogUtil.info(TAG + " init ParticipantsDialog, posX: " + posX + ", posY: " + posY);
        dlgWidth = (int) mContext.getResources().getDimension(R.dimen.def_dimens_1280);
        dlgHeight = (int) mContext.getResources().getDimension(R.dimen.def_dimens_1552);
        int gravity = Gravity.BOTTOM | Gravity.START;
        int xCoordinate = posX - dlgWidth / 2;
        int yCoordinate = posY + ConfConst.BOTTOM_CONF_HEIGHT + ConfConst.COMMON_MARGIN_Y;
        super.setWmPositionParams(gravity, xCoordinate, yCoordinate, dlgWidth, dlgHeight);
    }

    private void initEvent() {
        ivClose.setOnClickListener(view -> release());
        tvMuteAll.setOnClickListener(view -> handleMuteAll());
    }

    private void callBackToastNotify(int resId) {
        AppContext.instance().globalHandler.post(() -> Toast.makeText(mContext, resId, Toast.LENGTH_LONG));
    }

    private void handleMuteAll() {
        isAllMuted = !isAllMuted;
        LogUtil.info("handleMuteAll() ， isAllMuted now : " + isAllMuted);
        tvMuteAll.setText(isAllMuted ? R.string.cancel_mute_all : R.string.mute_all);
        MeetingManager.getInstance().muteAllAttendee(isAllMuted, new MeetingCallback<Integer>() {
            @Override
            public void onSuccess(Integer succMsg) {
                LogUtil.info("handleMuteAll() success : " + succMsg);
            }

            @Override
            public void onFailed(int errCode, String errMsg) {
                LogUtil.info("handleMuteAll() failed, errCode:" + errCode + ", errMsg:" + errMsg);
            }
        });
    }

    private void updateSpokesMan(Object obj) {
        if (obj instanceof ArrayList<?>) {
            List<Integer> userIdList = new ArrayList<>();
            for (Object object : (List<?>) obj) {
                if (object instanceof Integer) {
                    userIdList.add((Integer) object);
                }
            }
            List<String> speakerNameList = getSpeakerNameList(userIdList);
            updateSpokesman(speakerNameList);
        }
        if (obj instanceof String) {
            String spokesName = (String) obj;
            tvSpokesman.setText(spokesName);
        }
    }

    /**
     * 刷新发言人
     *
     * @param speakerNameList 发言人列表
     */
    private void updateSpokesman(List<String> speakerNameList) {
        LogUtil.info(TAG + " updateSpokesman() , nameList size : " + speakerNameList.size());
        llSecondSpokesman.setVisibility(speakerNameList.size() < 2 ? View.GONE : View.VISIBLE);
        if (speakerNameList.size() == 0) {
            tvSpokesman.setText(mContext.getString(R.string.no_speakr_site_txt));
            return;
        }
        if (speakerNameList.size() == 1) {
            tvSpokesman.setText(speakerNameList.get(0));
            return;
        }
        tvSpokesman.setText(speakerNameList.get(0));
        tvSecondSpokesman.setText(speakerNameList.get(1));
    }

    private List<String> getSpeakerNameList(List<Integer> userIdList) {
        // 更新发言方列表时，不需要重新请求数据，直接从本地缓存数据中查找即可
        List<String> nameList = new ArrayList<>();
        List<ParticipantInfo> listInCache = MeetingManager.getInstance().getParticipantListInCache();
        LogUtil.debug(TAG + " getSpeakerNameList, listInCache: " + listInCache.size());
        for (int i = 0; i < userIdList.size(); i++) {
            int tempUserId = userIdList.get(i);
            for (ParticipantInfo participantInfo : listInCache) {
                if (tempUserId == participantInfo.getUserId()) {
                    nameList.add(participantInfo.getSiteName());
                    break;
                }
            }
        }
        return nameList;
    }

    /**
     * 刷新与会者人数
     *
     * @param allCount    总会场数
     * @param inConfCount 入会数
     */
    public void refreshSiteCount(int allCount, int inConfCount) {
        LogUtil.info(TAG + " refreshSiteCount()");
        String numText = "";
        if (allCount == inConfCount) {
            numText = String.format(mContext.getString(R.string.participant_count), "" + allCount);
        } else { // 会中人数/总人数
            numText = String.format(mContext.getString(R.string.participant_count), inConfCount + "/" + allCount);
        }

        tvParticipantsCount.setText(numText);
    }

    private void initParticipantInfo() {
        LogUtil.info(TAG + " initParticipantInfo()");
        isHasChair = MeetingManager.getInstance().isHasChairman();
        isMeChairman = MeetingManager.getInstance().isMeChairman();
        LogUtil.info(TAG + " initParticipantInfo() , isMeChairman : " + isMeChairman);
        CopyOnWriteArrayList<GalleryBean> sites = new CopyOnWriteArrayList<>();
        List<ParticipantInfo> participantInfoList = MeetingManager.getInstance().getParticipantListInCache();
        if (participantInfoList != null) {
            int participantCount = participantInfoList.size();
            LogUtil.info(TAG + " participantInfoList.size() is : " + participantCount);
            updateAllMutedStatus(participantInfoList);
            loadConfSiteInfo(participantInfoList, sites);
            insertMultiFrame(sites);
            refreshParticipantLayout(sites);
        }
    }

    private void loadConfSiteInfo(List<ParticipantInfo> participantsInfo, CopyOnWriteArrayList<GalleryBean> sites) {
        isMeChairman = MeetingManager.getInstance().isMeChairman();

        for (ParticipantInfo participantInfo : participantsInfo) {
            ConfSiteInfo confSiteInfo = new ConfSiteInfo(participantInfo);
            if (!isMeChairman && !confSiteInfo.isJoinConf()) {
                continue; // 非主席不显示未入会的会场
            }
            sites.add(confSiteInfo);
        }
    }

    /**
     * 增加多画面会场
     *
     * @param sites 会场列表
     */
    private void insertMultiFrame(CopyOnWriteArrayList<GalleryBean> sites) {
        // 多流会议，不添加多画面虚拟会场
        boolean isMulti = MeetingManager.getInstance().isJoinConfStateMultiStream();
        if (!isMulti) {
            // 新增多画面
            ParticipantInfo participantInfo = new ParticipantInfo();
            participantInfo.setJoinConf(true);
            participantInfo.setSiteName(mContext.getString(R.string.mutipic_site_txt));
            TermCtrlSiteInfo termCtrlSiteInfo = MeetingManager.getInstance().getTermCtrlSiteInfo();
            if (termCtrlSiteInfo == null) {
                participantInfo.setViewed(false);
            } else {
                // userID = M * 10000 + T , T为0表示观看大画面
                participantInfo.setViewed((termCtrlSiteInfo.getSeeingUserId() % 10000 == 0));
            }

            ConfSiteInfo multiPicSite = new ConfSiteInfo(participantInfo);
            sites.add(multiPicSite);
        }
    }

    /**
     * 查询是否是全部静音状态
     * 1. 非主席，不需关注此状态
     * 2. 是主席，根据查询到的状态更新底部区域
     *
     * @param participantInfos 所有与会者列表
     */
    private void updateAllMutedStatus(List<ParticipantInfo> participantInfos) {
        if (!isMeChairman) {
            return;
        }
        for (ParticipantInfo participantInfo : participantInfos) {
            // 不需关注自己的mic状态
            if (participantInfo.getUserId() == MeetingManager.getInstance().getLocalUserId()) {
                continue;
            }
            if (participantInfo.isJoinConf() && !participantInfo.isMute()) {
                isAllMuted = false;
                return;
            }
        }
        isAllMuted = true;
    }

    private void refreshParticipantLayout(CopyOnWriteArrayList<GalleryBean> sites) {
        participantsAdapter.setData(sites);
        initChairStatus();
    }

    /**
     * 需申请主席
     */
    public void needChairNotify() {
        String notifyStr = "";
        if (isHasChair) {
            String hasChairStr = mContext.getString(R.string.conf_message_chair_exist_contact_notice);
            notifyStr = String.format(hasChairStr, "");
        } else {
            notifyStr = mContext.getString(R.string.refuse_opt_no_chair);
        }
        String finalNotifyStr = notifyStr;
        AppContext.instance().globalHandler.post(() -> Toast.makeText(mContext, finalNotifyStr,
                Toast.LENGTH_LONG).show());
    }

    /**
     * 语音会场不可被选看通知
     */
    public void watchVoiceSiteNotify() {
        AppContext.instance().globalHandler.post(
                () -> Toast.makeText(mContext, R.string.conf_control_message_view_voicesite_fail,
                        Toast.LENGTH_LONG).show());
    }

    public void showCallSiteNotify() {
        AppContext.instance().globalHandler.post(() -> Toast.makeText(mContext, R.string.participant_call_site,
                Toast.LENGTH_LONG).show());
    }

    /**
     * 观看会场失败通知
     *
     * @param errCode 错误码
     */
    public void watchSiteFailedNotify(int errCode) {
        LogUtil.error(TAG + " errCode:" + errCode);
        if (errCode != EventMsg.IDEA_MEETING_ON_CONFCTRL_WATCH_SITE_RESULT) {
            AppContext.instance().globalHandler.post(
                    () -> Toast.makeText(mContext, R.string.text_playback_abnormal,
                            Toast.LENGTH_LONG).show());
        }
    }

    @Override
    public void viewDataChanged(int eventId, Object obj) {
        LogUtil.info(TAG + " viewDataChanged , eventId : " + eventId);
        switch (eventId) {
            case ObserverConts.MSG_ATTENDESS_CHANGE_STATUS:
                initParticipantInfo();
                initChairStatus();
                break;
            case ObserverConts.FLOOR_SITE_LIST_IND:
                updateSpokesMan(obj);
                break;
            default:
                break;
        }
    }

    @Override
    public void unRegisterListenService() {
        LogUtil.info(TAG + " unRegisterListenService");
        MeetingManager.getInstance().unregistDataChangeListenerObj(this);
    }

    @Override
    public void release() {
        unRegisterListenService();
        super.release();
    }

    @Override
    public void registerListenerService() {
        LogUtil.info(TAG + " registerListenerService");
        MeetingManager.getInstance().registerObserved(ObserverConts.MSG_ATTENDESS_CHANGE_STATUS, this);
        MeetingManager.getInstance().registerObserved(ObserverConts.FLOOR_SITE_LIST_IND, this);
    }
}
